package org.chronologger.poppaea.client.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.chronologger.poppaea.client.overlap.Range;
import org.chronologger.poppaea.client.utils.Logger;
import org.chronologger.poppaea.client.widgets.SceneWidget;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class Scene implements Range, Iterable<Person>, Serializable {

	private static final long serialVersionUID = 1L;

	private Long id = null;

	private String title = "";
	private String notes;
	private String description;
	private String color = "white";

	private byte progress;

	private Long startTime;
	private Long endTime;
	private Long locationId;

	private transient List<Person> characters = new ArrayList<Person>();
	private transient Location location;
	private transient SceneWidget widget;
	private transient boolean updateLater = false;

	Scene() {
	}

	public Scene(Long id, Long locationId) throws NotSupportedOnClientException {
		if (GWT.isClient())
			throw new NotSupportedOnClientException();
		else {
			this.id = id;
			this.locationId = locationId;
		}
	}

	public void setStartTime(Long startTime) {
		this.startTime = startTime;
	}

	public Long getStartTime() {
		return startTime;
	}

	public void setEndTime(Long endTime) {
		this.endTime = endTime;
	}

	public Long getEndTime() {
		return endTime;
	}

	public void setProgress(byte progress) {
		this.progress = progress;
	}

	public byte getProgress() {
		return progress;
	}

	public void setNotes(String notes) {
		this.notes = notes;
	}

	public String getNotes() {
		return notes;
	}

	public void setLocation(Location location) {
		this.location = location;
		this.locationId = location.getId();
	}

	public Location getLocation() {
		return location;
	}

	void setId(Long id) {
		this.id = id;
		if (updateLater) {
			updateOnServer();
		}
	}

	public Long getId() {
		return id;
	}

	public int getFrom() {
		return (int) (startTime / 1000);
	}

	public int getTo() {
		return (int) (endTime / 1000);
	}

	public void setWidget(SceneWidget widget) {
		this.widget = widget;
	}

	public SceneWidget getWidget() {
		return widget;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getTitle() {
		return title;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getDescription() {
		return description;
	}

	public void addPerson(Person person) {
		characters.add(person);
	}

	public void removePerson(Person person) {
		characters.remove(person);
	}

	public Iterator<Person> iterator() {
		return characters.iterator();
	}

	public void setColor(String color) {
		this.color = color;
	}

	public String getColor() {
		return color;
	}

	public Long getLocationId() {
		return locationId;
	}

	public void updateOnServer() {
		if (id == null) {
			updateLater = true;
			Logger.notice("Not persisted yet, updating later");
		} else {
			ChronologyData.getService().updateScene(this,
					new AsyncCallback<Void>() {

						public void onFailure(Throwable caught) {
							Logger.error("Couldn't update scene");
						}

						public void onSuccess(Void result) {
							Logger.notice("Scene updated.");
						}
					});
		}
	}

}
